from interval import *
from interval import _compare_left_endpoint

class MultiInterval(object):
    
    def __init__(self, *args):
        """Right now this just takes strings representing intervals in the same way as in the Interval class. Multiple 
        intervals should be separated by an underscore. For example MultiInterval("(1, 2)"), or MultiInterval("(1, 2)_(5, 7]")"""
        if len(args) == 1:
            if isinstance(args[0], str):
                self._from_string(*args)
                
    def _from_string(self, interval_repr):
        assert re.compile('[[(][0-9]+, *[0-9]+[)\]](_[[(][0-9]+, *[0-9]+[)\]])*').match(interval_repr), 'Invalid formatting'
        
        representation = unicode(interval_repr).split("_")
        for rep in representation:
            rep = ''.join(unicode(rep).split())
        self.subintervals = []
        
        for subinterval in representation:
        
            start_bracket, end_bracket = subinterval[0], subinterval[-1]
            inclusive_table = {'(': False, ')': False, '[': True, ']':True}
            
            inclusive_start, inclusive_end = inclusive_table[start_bracket], inclusive_table[end_bracket]
        
            startstr, endstr = subinterval[1:-1].split(',') # FIXME: can error here, may be confusing-- should I catch it?
            start, end = float(startstr), float(endstr)
            
            self.subintervals.append(Interval(start, end, inclusive_start, inclusive_end))
        
        self.subintervals.sort(cmp=_compare_left_endpoint)
        
        i = 0
        while i < len(self.subintervals) - 1:
            if not (self.subintervals[i] & self.subintervals[i+1]).is_empty():
                self.subintervals[i] = self.subintervals[i].union(self.subintervals[i+1])
                self.subintervals = self.subintervals[:-1]
            else:
                i += 1
        
    
    def __or__(self, interval):
        """Returns the Union of this and the other (composite)interval"""
        pass
    
    def __and__(self, interval):
        """Returns the Intersection of this and the interval"""
        pass
    
    def __xor__(self, interval):
        """Returns the inverse of __and__ given the Universe?"""
        pass
    
    def __sub__(self, interval):
        pass
    
    def __invert__(self):
        """Returns inversion given the universe?"""
        pass
    
    def __contains__(self, value):
        return self.__bool__(value)
    
    def __bool__(self, value):
        return bool(self._bsearch(0, len(self.intervals)-1, value))
    
    def __str__(self):
        strep = ''
        for interval in self.subintervals:
            strep += str(interval) + " "
            
        return strep
    
    def __repr__(self):
        """Return a str representation of the object."""
        return '%s(%s)' % (type(self).__name__, repr(unicode(self)))
#simple test: x = CompositeInterval2(0, True, 1, False, 1, False, 2, True); 0 in x and 1 not in x and 2 in x